<script setup>
import { nextTick, ref, computed, onMounted, toRefs, watch, onBeforeUnmount } from 'vue';
import { useRoute } from 'vue-router';
import { ElCascader, ElMessage } from 'element-plus';
import 'mapbox-gl-compare/dist/mapbox-gl-compare.css';
import { getRelationById } from '@/apis/api-map-server';
import { load } from '@/common/common-loading';
import BorderBoxBg from '@/components/BorderBoxBg.vue';
import { LAYERS_GROUP_ID } from '@/utils/map-helper';
import {
  ADD_LAYER_TO_MAP_BOX_MAP,
  REMOVE_MAPBOX_LAYER,
  AGENCY_MAP_SERVER,
  REMOVE_DRAW,
  GET_MAPBOX_MAP,
  ADD_DRAW,
  POINT_QUERY_FUN,
  High_Light_LAYER, // REST_MAP_FIT_BOUNDS,
  SPACE_QUERY_FUN,
} from '@/utils/map-utils';

const cascaderProps = {
  emitPath: false,
};

const props = defineProps({
  resultFeatures: Object,
});
const { resultFeatures } = toRefs(props);

let flag = false;

const emit = defineEmits(['attributeClose', 'handleQueryInfo']);

const layerList = computed(() => {
  return mapImgList.value.map((item) => item?.children || []).flat(1);
});

const mapImgList = ref([]);
const route = useRoute();
const checkedTypeBtn = ref('');
const checked_layer = ref('1');
const attResult = ref(null);
const layerValue = ref('');

watch(
  resultFeatures,
  (val) => {
    if (!Object.keys(val).length) {
      clearLightLayer();
    }
  },
  { deep: true },
);

const getRelationByIdApi = async () => {
  const [err, data] = await getRelationById({
    menuCode: route.query?.code,
  });

  if (!err) {
    mapImgList.value = data.map((item) => {
      return {
        ...item,
        label: item.serviceName,
        value: item.serviceName,
        children:
          item?.children?.map((el) => {
            let id = `${item.id}${Math.random()}`;

            return {
              ...el,
              fid: item.id,
              id,
              label: el.layerMeta.name,
              value: id,
              url: AGENCY_MAP_SERVER(item, el),
            };
          }) || [],
      };
    });
  }
};

// 关闭弹窗 并清理数据
const handleClose = () => {
  handleClearResult();
  // REST_MAP_FIT_BOUNDS();
  REMOVE_MAPBOX_LAYER(LAYERS_GROUP_ID.TD_MAP_LAYER);

  emit('attributeClose');
};

//图层选择
const handleChange = (e) => {
  handleClearResult();

  let target = layerList.value.find((el) => el.id == e);

  if (target) {
    checked_layer.value = target;

    nextTick(() => {
      ADD_LAYER_TO_MAP_BOX_MAP(LAYERS_GROUP_ID.TD_MAP_LAYER, target);
    });
  }
};

onMounted(() => {
  getRelationByIdApi();
});

const handleMapAttributeQuery = (type) => {
  emit('handleQueryInfo', {}, 'spatial_point', '属性查询', 2);
  emit('handleQueryInfo', {}, 'spatial_polygon', '属性查询', 2);

  if (checked_layer.value == '1') {
    ElMessage({
      message: '请选择图层',
      duration: 1000,
      type: 'warning',
    });

    return;
  }

  checkedTypeBtn.value = type;

  const map = GET_MAPBOX_MAP();

  // 清除高亮图层
  clearLightLayer();
  REMOVE_DRAW();

  map.getCanvas().style.cursor = 'crosshair';

  map.off('click', mapCallBackPoint);
  map.off('draw.create', handlePolygonQuery);

  if (type == 'spatial_point') {
    map.on('click', mapCallBackPoint);
  } else if (type == 'spatial_polygon') {
    map.off('click', mapCallBackPoint);

    ADD_DRAW({ defaultMode: 'draw_polygon' });

    map.on('draw.create', handlePolygonQuery);
  }
};

// 点查询

const mapCallBackPoint = async (e) => {
  if (attResult.value?.length) {
    clearLightLayer();
  }

  if (flag) {
    return;
  }

  let mapParams = {
    id: checked_layer.value.fid,
    TYPENAME: checked_layer.value.label.replace('.shp', ''),
    lng: e.lngLat.lng,
    lat: e.lngLat.lat,
  };

  flag = true;

  load.show('正在获取属性信息，请稍等...');

  const queryInfo = await POINT_QUERY_FUN(mapParams);

  if (queryInfo.features.length) {
    ElMessage({
      message: '查询成功',
      duration: 1000,
      type: 'success',
    });

    attResult.value = queryInfo.features;

    const infoLayer = {
      layerKey: checked_layer.value.label,
      tableList: [],
    };

    for (let key in queryInfo.features[0].properties) {
      let info = {};

      info['key'] = key;
      info['value'] = queryInfo.features[0].properties[key];

      infoLayer.tableList.push(info);
    }

    infoLayer.tableList.unshift({
      key: '图层名称',
      value: checked_layer.value.label,
    });

    const layerId = LAYERS_GROUP_ID.High_Light_RESULT_LAYER;

    High_Light_LAYER(layerId, queryInfo.features);
    emit('handleQueryInfo', infoLayer, 'spatial_point', '属性查询', 2);
  } else {
    ElMessage({
      message: '未查询到任何要素',
      duration: 1000,
      type: 'info',
    });

    emit('handleQueryInfo', {}, 'spatial_point', '属性查询', 2);
  }

  flag = false;
  load.hide();
};

// 框选查询

const handlePolygonQuery = async (e) => {
  if (attResult.value?.length) {
    clearLightLayer();
  }

  if (flag) {
    return;
  }

  let mapParams = {
    id: checked_layer.value.fid,
    TYPENAME: checked_layer.value.label.replace('.shp', ''),
    coordinates: e.features[0].geometry.coordinates,
  };

  flag = true;

  load.show('正在获取属性信息，请稍等...');

  const queryInfo = await SPACE_QUERY_FUN(mapParams);

  if (queryInfo.features.length) {
    ElMessage({
      message: '查询成功',
      duration: 1000,
      type: 'success',
    });

    attResult.value = queryInfo.features;

    const layerId = LAYERS_GROUP_ID.High_Light_RESULT_LAYER;

    High_Light_LAYER(layerId, queryInfo.features);
    emit('handleQueryInfo', queryInfo, 'spatial_polygon', '属性查询', 2);
  } else {
    ElMessage({
      message: '未查询到任何要素',
      duration: 1000,
      type: 'info',
    });

    emit('handleQueryInfo', {}, 'spatial_polygon', '属性查询', 2);
  }

  flag = false;
  load.hide();
};

// 重新查询
const handleClearResult = () => {
  const map = GET_MAPBOX_MAP();

  if (attResult.value?.length) {
    clearLightLayer();
  }

  REMOVE_DRAW();

  if (map) {
    map.off('click', mapCallBackPoint);
    map.off('draw.create', handlePolygonQuery);
    map.getCanvas().style.cursor = 'pointer';
  }

  checkedTypeBtn.value = '';

  emit('handleQueryInfo', {}, checked_layer, '属性查询', 2);
};

// 清除高亮图层
const clearLightLayer = () => {
  const layerId = LAYERS_GROUP_ID.High_Light_RESULT_LAYER;

  for (let i = 0; i < attResult.value?.length; i++) {
    REMOVE_MAPBOX_LAYER(`${layerId}~light${i}`);
  }
};

onBeforeUnmount(() => {
  handleClose();
});
</script>
<template>
  <BorderBoxBg title="属性查询" class="attribute bottom-52px" @close="handleClose">
    <div class="cutting-box">
      <div class="item pl-10px">
        <ElCascader
          v-model="layerValue"
          popper-class="cutting-pop bg-blue-400"
          class="pops"
          placeholder="选择图层"
          :options="mapImgList"
          :props="cascaderProps"
          @change="handleChange"
        />
      </div>
      <div class="item-btn mt-20px flex flex-col justify-center gap-20px pt-10px">
        <div
          :type="checkedTypeBtn == 'spatial_point' ? 'primary' : ''"
          @click="handleMapAttributeQuery('spatial_point')"
        >
          空间（点）
        </div>
        <div
          :type="checkedTypeBtn == 'spatial_polygon' ? 'primary' : ''"
          @click="handleMapAttributeQuery('spatial_polygon')"
        >
          空间（框选）
        </div>
        <div @click="handleClearResult">重新查询</div>
      </div>
    </div>
  </BorderBoxBg>
</template>

<style scoped lang="scss">
.attribute {
  top: 50%;
  bottom: auto;
}
.item-btn {
  div {
    height: 40px;
    margin: 0 10px;
    line-height: 40px;
    text-align: center;
    background-color: #0dc4c49d;
    border-radius: 5px;
    cursor: pointer;
    &:hover {
      background-color: #0dc4c4e0;
    }
  }
}
</style>
